package com.zero2oneit.mall.search.service.impl;

import com.zero2oneit.mall.common.utils.EsIndexConstant;
import com.zero2oneit.mall.common.utils.R;
import com.zero2oneit.mall.common.utils.StringUtils;
import com.zero2oneit.mall.common.utils.bootstrap.BoostrapDataGrid;
import com.zero2oneit.mall.search.feign.goods.BusinessFeign;
import com.zero2oneit.mall.search.mapper.EsGoodProMapper;
import com.zero2oneit.mall.search.qo.IndexSearchQo;
import com.zero2oneit.mall.search.qo.ShopTypeGoodQo;
import com.zero2oneit.mall.search.service.GoodProEsService;
import com.zero2oneit.mall.search.vo.BusinessGoods;
import com.zero2oneit.mall.search.vo.YzProSkuVo;
import com.zero2oneit.mall.search.vo.YzProVo;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

import static org.elasticsearch.index.query.QueryBuilders.*;

/**
 * @author Lee
 * @date 2020/7/30 -15:30
 */
@Service
public class GoodProEsServiceImpl implements GoodProEsService {

    @Autowired
    private EsGoodProMapper esMapper;

    @Autowired
    private BusinessFeign businessFeign;

    public List productSkuByProId(String id) {
        return esMapper.esSelectList(EsIndexConstant.SKU_INDEX, termQuery("productId", id), Map.class,null);
    }

    @Override
    public Map skuListStock(List<String> list) {
        return esMapper.skuListStock(list,EsIndexConstant.SKU_INDEX,new String[] {"productStock","fnPrice"});
    }

    @Override
    public Map getByIndexAndId(String index,String id) {
        boolean exists = esMapper.exists(index,id);
        if (exists){
            GetResponse response = esMapper.getById(index, id);
            return response.getSource();
        }
        return null;
    }

    @Override
    public R keywordSearch(Map<String,String> map) {
        if (!StringUtils.isEmpty(map.get("keyword"))){
            BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery()
                    .must(boolQuery().should(matchPhraseQuery("productName",map.get("keyword")))
                            .should(matchPhraseQuery("productTypeName",map.get("keyword")))
                            .should(matchPhraseQuery("productDesc",map.get("keyword"))));
            if (!StringUtils.isEmpty(map.get("plateIds"))){
                queryBuilder.must(boolQuery().should(wildcardQuery("plateIds", map.get("plateIds")+"_*"))
                        .should(wildcardQuery("plateIds", "*_" + map.get("plateIds") + "_*"))
                        .should(wildcardQuery("plateIds", "*_" + map.get("plateIds"))));
            }
            queryBuilder.must(termQuery("appType",map.get("appType")));
            return R.ok(esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,
                    (Integer.parseInt(map.get("currentPage"))-1)*Integer.parseInt(map.get("size")),
                    Integer.parseInt(map.get("size")),map.get("sort"),null));
        }
        return R.fail("请输入关键字");
    }

    @Override
    public BoostrapDataGrid myProSearch(Map<String, String> map, String index) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().
                must(termQuery("businessId",map.get("businessId"))).must(termQuery("appType",map.get("appType")));
        if (!StringUtils.isEmpty(map.get("keyword"))){
               queryBuilder.must(matchQuery("productName",map.get("keyword")));
        }
        return esMapper.esSelectCommon(index,queryBuilder,Map.class,
                (Integer.parseInt(map.get("currentPage"))-1)*Integer.parseInt(map.get("size")),
                Integer.parseInt(map.get("size")),map.get("sort"),null);
    }

    @Override
    public BoostrapDataGrid yzProSearch(Map<String, String> map) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery().must(matchPhraseQuery("productName",map.get("keyword"))).must(termQuery("appType",map.get("appType")));
        BoostrapDataGrid boostrapDataGrid = esMapper.esSelectCommon(EsIndexConstant.GOOD_FNYZ_INDEX, queryBuilder, Map.class,
                null, null, null,1);
        List<Map> rows = (List<Map>) boostrapDataGrid.getRows();
        if (rows.size()!=0){
            Map skuMap = esMapper.yzSkuList(rows, EsIndexConstant.SKU_INDEX);
            List<YzProSkuVo> skuVoList =new ArrayList<>();
            for (int i = 0; i < rows.size(); i++) {
                List<SearchHit> hitList = Arrays.asList((SearchHit[])skuMap.get(rows.get(i)));
                List<Map> list=new ArrayList<>();
                for (int j = 0; j < hitList.size(); j++) {
                    Map sourceAsMap = hitList.get(j).getSourceAsMap();
                    list.add(sourceAsMap);
                }
                skuVoList.add(new YzProSkuVo(rows.get(i),list));
            }
            return  new BoostrapDataGrid(boostrapDataGrid.getTotal(), boostrapDataGrid.getTotal() ==0 ? Collections.EMPTY_LIST :skuVoList);
        }
        return boostrapDataGrid;
    }



    @Override
    public BoostrapDataGrid businessSearch(Map<String, String> map) {
        BoostrapDataGrid dataGrid = esMapper.esSelectCommon(EsIndexConstant.FNYG_BUSINESS, matchQuery("businessName", map.get("keyword")),
                Map.class, (Integer.parseInt(map.get("currentPage")) - 1) * Integer.parseInt(map.get("size")),
                Integer.parseInt(map.get("size")), null,null);
        List<Map<String,String>> rows = (List<Map<String, String>>) dataGrid.getRows();
        if (rows.size()!=0){
            Map listShop = esMapper.proListShop(rows, EsIndexConstant.GOOD_INDEX);
            List<BusinessGoods> resultList =new ArrayList<>();
            for (int i = 0; i < rows.size(); i++) {
                Map<String,Map> shop = (Map) listShop.get(rows.get(i));
                resultList.add(new BusinessGoods(rows.get(i).get("businessId"),rows.get(i).get("businessName"),shop.get("hits")));
            }
            return new BoostrapDataGrid(dataGrid.getTotal(), dataGrid.getTotal() ==0 ? Collections.EMPTY_LIST :resultList);
        }
        return dataGrid;
    }

    @Override
    public BoostrapDataGrid indexProList(IndexSearchQo qo) {
        String type;
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        if (!StringUtils.isEmpty(qo.getPlateIds())) {
/*            queryBuilder.must(QueryBuilders.boolQuery().should(wildcardQuery("plateIds", qo.getPlateIds()+"_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds() + "_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds())));*/

            queryBuilder.should(wildcardQuery("plateIds", qo.getPlateIds()+"_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds() + "_*"))
                    .should(wildcardQuery("plateIds", "*_" + qo.getPlateIds())).minimumShouldMatch(1);

        }else {
            queryBuilder.must(termQuery("isRecommend","1"));
        }
        if (qo.getId()!=0){
            if (qo.getLevel()==1){
                type="oneType";
            }else if (qo.getLevel()==2){
                type="twoType";
            }else if (qo.getLevel()==3){
                type="threeType";
            }else {
                type="fourType";
            }
            queryBuilder.must(termQuery(type,String.valueOf(qo.getId())));
        }
        return esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,qo.getStarIndex(),qo.getPageSize(),"index",null);
    }

    @Override
    public Map
    yzSearch() {
        R r = businessFeign.getByAll();
        List<Map> typeList= (List<Map>) r.getData();
        Map map = esMapper.yzSearch();
        List<SearchHit> proList = Arrays.asList((SearchHit[]) map.get("proHit"));
        List<SearchHit> skuList = Arrays.asList((SearchHit[]) map.get("skuHit"));

        List<YzProVo>  resultList=new ArrayList<>(typeList.size());
        typeList.forEach(typeMap->{
            YzProVo proVo=new YzProVo();
            proVo.setName((String) typeMap.get("name"));
            proList.forEach(proHit->{
                Map<String, Object> proMap = proHit.getSourceAsMap();
                String[] bussTypeArr = String.valueOf(proMap.get("bussTypeId")).split(",");
                List<String> list = Arrays.asList(bussTypeArr);
                if (list.contains(String.valueOf(typeMap.get("id")))){
                    YzProSkuVo yzProSkuVo = new YzProSkuVo();
                    proMap.put("count",0);
                    yzProSkuVo.setMap(proMap);
                    skuList.forEach(skuHit->{
                        Map<String, Object> skuMap = skuHit.getSourceAsMap();
                        if (skuMap.get("productId").equals(proMap.get("productId"))){
                            skuMap.put("count",0);
                            yzProSkuVo.getSkuList().add(skuMap);
                        }
                    });
                    proVo.getList().add(yzProSkuVo);
                }
            });
            resultList.add(proVo);
        });
        Map<String,Object> resultMap=new HashMap<>(2);
        resultMap.put("typeList",typeList);
        resultMap.put("list",resultList);
        return resultMap;
    }

    @Override
    public R yzBusinessTypeSearch(ShopTypeGoodQo qo) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(termsQuery("appType",qo.getAppType()));
        queryBuilder.should(termQuery("bussTypeId", qo.getBussTypeId()))
                .should(wildcardQuery("bussTypeId", qo.getBussTypeId() + ",*"))
                .should(wildcardQuery("bussTypeId", "*," + qo.getBussTypeId())).minimumShouldMatch(1);
        BoostrapDataGrid boostrapDataGrid = esMapper.esSelectCommon(EsIndexConstant.GOOD_FNYZ_INDEX, queryBuilder, Map.class, qo.getStarIndex(), qo.getPageSize(), "index", 2);
        if (boostrapDataGrid.getTotal()>0){
            List<?> goodList = boostrapDataGrid.getRows();
            HashSet<String> goodIdSet=new HashSet<>(goodList.size());
            Map goodMap;
            for (int i = 0; i < goodList.size(); i++) {
                goodMap = (Map) goodList.get(i);
                goodIdSet.add(String.valueOf(goodMap.get("productId")));
            }
            queryBuilder=QueryBuilders.boolQuery();
            queryBuilder.must(termsQuery("productId",goodIdSet));
            List list = esMapper.esSelectList(EsIndexConstant.SKU_INDEX, queryBuilder, Map.class, null);
            String productId;
            String skuProId;
            Map skuMap;
            YzProSkuVo yzProSkuVo;
            List<YzProSkuVo> yzProList=new ArrayList<>();
            for (int i = 0; i < goodList.size(); i++) {
                goodMap = (Map) goodList.get(i);
                goodMap.put("count",0);
                yzProSkuVo= new YzProSkuVo();
                yzProSkuVo.setMap(goodMap);
                productId=String.valueOf(goodMap.get("productId"));
                for (int j = 0; j < list.size(); j++) {
                    skuMap = (Map) list.get(j);
                    skuMap.put("count",0);
                    skuProId = String.valueOf(skuMap.get("productId"));
                    if (skuProId.equals(productId)){
                        yzProSkuVo.getSkuList().add(skuMap);
                    }
                }
                yzProList.add(yzProSkuVo);
            }
            return R.ok(new BoostrapDataGrid(boostrapDataGrid.getTotal(),yzProList));
        }else {
            return R.ok(boostrapDataGrid);
        }

    }

    // businessId 商家id  String bussTypeId商家分类id
    @Override
    public BoostrapDataGrid businessType(ShopTypeGoodQo qo) {
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(termQuery("businessId",qo.getBusinessId()));
        queryBuilder.must(termQuery("bussTypeId",qo.getBussTypeId()));
        return esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,qo.getStarIndex(),qo.getPageSize(),null,null);
    }

    @Override
    public Map hotGood() {
        return esMapper.hotGood();
    }

    @Override
    public BoostrapDataGrid sortSearch(Map<String, String> map) {
        String level = map.get("level");
        String id = map.get("id");
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        String type="";
        if ("1".equals(level)){
           type="oneType";
        }else if ("2".equals(level)){
            type="twoType";
        }else if ("3".equals(level)){
            type="threeType";
        }else if ("4".equals(level)){
            type="fourType";
        }
        queryBuilder.must(termQuery(type,id));
        queryBuilder.must(termQuery("appType",map.get("appType")));
        return esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX,queryBuilder,Map.class,
                (Integer.parseInt(map.get("currentPage"))-1)*Integer.parseInt(map.get("size")),
                Integer.parseInt(map.get("size")),map.get("sort"),null);
    }

    /**
     * 驿站与自营店
     * @param map
     * @return
     */
    @Override
    public BoostrapDataGrid courierStation(Map<String, String> map) {
        String yzBusId = map.get("businessId");
        String ruleId = map.get("ruleId");
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        queryBuilder.must(termQuery("businessId",yzBusId));
        queryBuilder.must(boolQuery().should(termQuery("ruleId",0)).should(termQuery("ruleId",ruleId)));
        if(("0").equals(yzBusId)){
            //0-烽鸟自营店
            BoostrapDataGrid result = esMapper.esSelectCommon(EsIndexConstant.GOOD_INDEX, queryBuilder,
                    Map.class, (Integer.parseInt(map.get("currentPage")) - 1) * Integer.parseInt(map.get("pageSize")),
                    Integer.parseInt(map.get("pageSize")), null,null);
            return result;
        }else {
            BoostrapDataGrid result = esMapper.esSelectCommon(EsIndexConstant.GOOD_FNYZ_INDEX, queryBuilder,
                    Map.class, (Integer.parseInt(map.get("currentPage")) - 1) * Integer.parseInt(map.get("pageSize")),
                    Integer.parseInt(map.get("pageSize")), null,null);
            return result;
        }

    }

    /**
     * 全不选  ruleId  0
     * @param map
     */
    @Override
    public void chooseRule(Map<String, String> map) {
        String businessId = map.get("businessId");
        String ruleId = map.get("ruleId");
        //0-烽鸟易购自营店 1-驿站
        if("0".equals(businessId)){
            esMapper.getBusId(EsIndexConstant.GOOD_INDEX,businessId,ruleId,"1");
        }else {
            esMapper.getBusId(EsIndexConstant.GOOD_FNYZ_INDEX,businessId,ruleId,"1");
        }


    }

    //全选
    @Override
    public void selectAllRule(Map<String, String> map) {

        String businessId = map.get("businessId");
        String ruleId = map.get("ruleId");
        //0-烽鸟易购自营店 1-驿站
        if("0".equals(businessId)){
            esMapper.getBusId(EsIndexConstant.GOOD_INDEX,businessId,ruleId,"0");
        }else {
            esMapper.getBusId(EsIndexConstant.GOOD_FNYZ_INDEX,businessId,ruleId,"0");
        }

    }

    //确定按钮
    @Override
    public synchronized void buttonRule(Map map) {
        List<Map> choose= (List<Map>) map.get("choose");
        String ruleIdplus = (String) map.get("ruleIdplus");
        String businessId = (String) map.get("busId");
        //0烽鸟自营店  1驿站
        if("0".equals(businessId)){
            //先编辑为-1

            Boolean byProIds= esMapper.getUpdateByProIds(EsIndexConstant.GOOD_INDEX,choose,"-1");
            System.out.println("第一步");
            //再查出来是本身ruleIdplus 编辑为0
            try {
                Thread.sleep(3000);
            }catch (Exception e){
                e.printStackTrace();
            }

            if(byProIds){
                System.out.println("第二步");
                Boolean busIdButton = esMapper.getBusIdButton(EsIndexConstant.GOOD_INDEX, businessId, ruleIdplus, "-1");
                if(busIdButton){
                    //再把-1 编辑为 选中的ruledplus
                    esMapper.getBusIdButton(EsIndexConstant.GOOD_INDEX,businessId,ruleIdplus,"1");
                    System.out.println("第三步");
                }
            }

        }else {
            esMapper.getUpdateByProIds(EsIndexConstant.GOOD_FNYZ_INDEX,choose,"-1");
            //再查出来没有ruleIdplus 为0
            try {
                Thread.sleep(3000);
            }catch (Exception e){
                e.printStackTrace();
            }
            Boolean busIdButton = esMapper.getBusIdButton(EsIndexConstant.GOOD_FNYZ_INDEX, businessId, ruleIdplus, "-1");
            if(busIdButton){
                //再把-1 编辑为 选中的ruledplus
                esMapper.getBusIdButton(EsIndexConstant.GOOD_FNYZ_INDEX,businessId,ruleIdplus,"1");
            }

        }

    }

    @Override
    public Map yzProductSku(String skuIndex,String proIndex,String id, String productId) {
        return esMapper.yzProductSku(skuIndex,proIndex,id,productId);
    }

    @Override
    public List<Map> purchasedSku(List<Map> list) {
        List<Map> resultList=new ArrayList<>(list.size());
        for (Map map : list) {
            resultList.add(yzProductSku(EsIndexConstant.SKU_INDEX,EsIndexConstant.GOOD_FNYZ_INDEX,String.valueOf(map.get("skuId")),String.valueOf(map.get("productId"))));
        }
        return resultList;
    }



}
